﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace TFSTools.TFSLibrary
{
    public sealed class TFSFieldInfo : TFSServerEntity, IComparable<TFSFieldInfo>
    {
        private Field serverField;

        internal TFSFieldInfo(ITFSConnection connection, Field field)
            : base(connection)
        {
            this.serverField = field;
        }

        public int Id { get { return this.serverField.Id; } }

        public string Name { get { return this.serverField.Name; } }

        public string ReferenceName { get { return this.serverField.ReferenceName; } }

        public object Value 
        {
            get { return this.serverField.Value; }
            set { this.serverField.Value = value; }
        }

        /// <summary>
        /// Gets the value as string.  If null, returns Empty string.
        /// </summary>
        /// <value>The value string.</value>
        public string ValueString 
        { 
            get 
            {
                if (this.serverField.Value == null)
                {
                    return string.Empty;
                }

                return this.serverField.Value.ToString();
            } 
        }

        /// <summary>
        /// Gets the value as 32 bit integer.  If not 32 bit integer, returns 0.
        /// </summary>
        /// <value>The value.</value>
        public int ValueInt32
        {
            get
            {
                object value = this.serverField.Value;

                if (value == null)
                {
                    return 0;
                }

                if (value is int)
                {
                    return (int)value;
                }

                if (value is string)
                {
                    int result;
                    int.TryParse((string)this.serverField.Value, out result);
                    return result;
                }

                return 0;
            }
        }

        /// <summary>
        /// Gets the value as Decimal.  If not Decimal, returns 0.
        /// </summary>
        /// <value>The value.</value>
        public decimal ValueDecimal
        {
            get
            {
                object value = this.serverField.Value;

                if (value == null)
                {
                    return 0;
                }

                if (value is decimal)
                {
                    return (decimal)value;
                }

                if (value is string)
                {
                    decimal result;
                    decimal.TryParse((string)this.serverField.Value, out result);
                    return result;
                }

                return 0;
            }
        }

        /// <summary>
        /// Gets the value as Double.  If not Decimal, returns 0.
        /// </summary>
        /// <value>The value Double.</value>
        public double ValueDouble
        {
            get
            {
                object value = this.serverField.Value;

                if (value == null)
                {
                    return 0;
                }

                if (value is double)
                {
                    return (double)value;
                }

                if (value is string)
                {
                    double result;
                    double.TryParse((string)this.serverField.Value, out result);
                    return result;
                }

                return 0;
            }
        }

        /// <summary>
        /// Gets the value as DateTime.  If not DateTime, returns DateTime.MinValue.
        /// </summary>
        /// <value>The value date time.</value>
        public DateTime ValueDateTime
        {
            get
            {
                object value = this.serverField.Value;

                if (value == null)
                {
                    return DateTime.MinValue;
                }

                if (value is DateTime)
                {
                    return (DateTime)value;
                }

                if (value is string)
                {
                    DateTime result;
                    DateTime.TryParse((string)this.serverField.Value, out result);
                    return result;
                }

                return DateTime.MinValue;
            }
        }

        public override string ToString() { return this.serverField.Name; }

        #region IComparable<TFSFieldInfo> Members

        public int CompareTo(TFSFieldInfo other)
        {
            return this.ValueString.CompareTo(other.ValueString);
        }

        #endregion
    }

    public sealed class TFSFieldInfoCollection : TFSServerEntityCollection<TFSFieldInfo>
    {
        public TFSFieldInfoCollection(ITFSConnection connection)
            : base(connection)
        {
        }

        public TFSFieldInfoCollection(ITFSConnection connection, IList<TFSFieldInfo> list)
            : base(connection, list)
        {
        }

        public TFSFieldInfoCollection(ITFSConnection connection, int capacity)
            : base(connection, capacity)
        {
        }

        internal static TFSFieldInfoCollection Create(ITFSConnection connection, FieldCollection collection)
        {
            List<TFSFieldInfo> list = new List<TFSFieldInfo>(collection.Count);

            foreach (Field field in collection)
            {
                list.Add(new TFSFieldInfo(connection, field));
            }

            return new TFSFieldInfoCollection(connection, list);
        }

        public TFSFieldInfo this[TFSCoreField coreField]
        {
            get
            {
                int id = (int)coreField;

                foreach (var field in this)
                {
                    if (field.Id == id)
                    {
                        return field;
                    }
                }

                return this[coreField.ToString()];
            }
        }

        public TFSFieldInfo this[string name]
        {
            get
            {
                foreach (var field in this)
                {
                    if (field.Name == name)
                    {
                        return field;
                    }
                }

                throw new TFSFieldNotExistException(name);
            }
        }

        public TFSFieldInfo FromReferenceName(string fieldReferenceName)
        {
            foreach (var field in this)
            {
                if (field.ReferenceName == fieldReferenceName)
                {
                    return field;
                }
            }

            return this[fieldReferenceName];
        }
    }
}
